package br.com.viamais.util;

import java.util.HashSet;
import java.util.Set;

import javax.faces.context.FacesContext;
import javax.servlet.http.HttpSession;

import br.com.viamais.dao.UserDAO;
import br.com.viamais.enumerator.Permission;
import br.com.viamais.model.Role;
import br.com.viamais.model.User;

/**
 * Class to manager user login. All of method this class are static. Can be
 * accessed from all system.
 * 
 * TODO: Logger
 * 
 * @author eduardo.dev
 */
public final class ManagerLogin {

	/**
	 * Session attribute name.
	 */
	private static final String USER_SESSION_ATTRIBUTE = MessageBundleUtil
			.getValue("configuration.session.attribute.user");

	/**
	 * Verify if exists permissions to current user logged in session. If user
	 * contains at least one permission, this method returns true.
	 * 
	 * @param Permission
	 *            : Array of permissions.
	 * @return boolean: If user contains at least one permission, this method
	 *         returns true.
	 * @throws Throwable
	 *             : Hibernate Connections problems.
	 */
	public static boolean hasPermission(Permission... permissions)
			throws Throwable {
		User user = getUserLogged();
		if ((user != null) && (permissions != null)) {
			Set<Role> userRoles = new HashSet<Role>();
			if ((user.getProfile() != null)
					&& (user.getProfile().getRoles() != null)) {
				userRoles = user.getProfile().getRoles();
			}
			for (Permission permission : permissions) {
				for (Role role : userRoles) {
					if (role.getPermission().getName() == permission.getName()) {
						return true;
					}
				}
			}
		}
		return false;
	}

	/**
	 * Get the user logged within session from database.
	 * 
	 * @return User: logged user.If there not a session user, return null.
	 * @throws Throwable
	 *             : Connections problems.
	 */
	public static User getUserLogged() throws Throwable {
		User user = null;
		HttpSession session = (HttpSession) FacesContext.getCurrentInstance()
				.getExternalContext().getSession(false);
		if (session != null) {
			Object object = session.getAttribute(USER_SESSION_ATTRIBUTE);
			if ((object != null) && (object instanceof User)) {
				user = (User) object;
				user = new UserDAO().getById(user.getId());
			}
		}
		return user;
	}

	/**
	 * Do user login in session.
	 * 
	 * @param String
	 *            : user name.
	 * @param String
	 *            : user password.
	 * 
	 * @return User: If successful login, return a instance of user, else return
	 *         NULL.
	 * @throws Throwable
	 *             : Connections problems.
	 */
	public static User doLogin(String username, String password)
			throws Throwable {
		User user = null;
		HttpSession session = (HttpSession) FacesContext.getCurrentInstance()
				.getExternalContext().getSession(false);
		user = new UserDAO().getByUserNamePassword(username, password);
		if ((user != null) && (session != null)) {
			session.removeAttribute(USER_SESSION_ATTRIBUTE);
			session.setAttribute(USER_SESSION_ATTRIBUTE, user);
		}
		return user;
	}

	/**
	 * Method doLogoff
	 * 
	 * @throws Throwable
	 *             : HttpSession problem.
	 */
	public static void doLogoff() throws Throwable {
		HttpSession session = (HttpSession) FacesContext.getCurrentInstance()
				.getExternalContext().getSession(false);
		if ((session != null)
				&& (session.getAttribute(USER_SESSION_ATTRIBUTE) != null)) {
			session.removeAttribute(USER_SESSION_ATTRIBUTE);
		}
	}
}
